package com.miracle9.game.service;

import com.miracle9.game.bean.RoomStatus;
import com.miracle9.game.dao.*;
import com.miracle9.game.entity.*;
import com.miracle9.game.enums.GameTypeEnums;
import com.miracle9.game.server.message.MessageSend;
import com.miracle9.game.server.message.StorageMethodEntity;
import com.miracle9.game.server.message.WaterSocketHandler;
import com.miracle9.game.util.GameParameterAssist;
import com.miracle9.game.util.MyUtil;
import org.apache.log4j.Logger;
import org.apache.mina.core.session.IoSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("waterDeskService")
public class WaterDeskService extends BaseService {

    private static final Logger logger = Logger.getLogger(WaterDeskService.class);
    private int gameType = GameTypeEnums.GT_7.getType();
    private String gameName = GameTypeEnums.GT_7.getName();
    private String gameNameEn = GameTypeEnums.GT_7.getEname();
    @Autowired
    private DeskService deskService;
    @Autowired
    private UserServiceDao userServiceDao;
    @Autowired
    private AdminServiceDao adminServiceDao;
    @Autowired
    private AdminLogServiceDao adminLogServiceDao;
    @Autowired
    private WaterRoomServiceDao waterRoomServiceDao;
    @Autowired
    private WaterDeskServiceDao waterDeskServiceDao;
    @Autowired
    private SystemConfigServiceDao systemConfigServiceDao;

    private void amfMessageSend(IoSession session, String method, Object result) {
        AmfMessageSend.send(new Data(session, method, new Object[]{result}));
    }

    private void addAdminLog(IoSession session, WaterDesk desk, String content, String contentEn) {
        Integer adminId = Integer.valueOf(session.getAttribute("id").toString());
        Admin admin = (Admin) this.adminServiceDao.getById(adminId);
        AdminLog adminLog = new AdminLog(admin.getUsername(), content, 1, admin.getType(), contentEn);
        this.adminLogServiceDao.addAdminLog(adminLog);
        for (IoSession s : WaterSocketHandler.F) {
            AmfMessageSend.send(new Data(s, "manageService/updateDesk", new Object[]{desk}));
        }
    }

    private void addAdminLog(IoSession session, String content, String contentEn) {
        Integer adminId = Integer.valueOf(session.getAttribute("id").toString());
        Admin admin = (Admin) this.adminServiceDao.getById(adminId);
        AdminLog adminLog = new AdminLog(admin.getUsername(), content, 1, admin.getType(), contentEn);
        this.adminLogServiceDao.addAdminLog(adminLog);
    }

    private String getRoomTypeName(int roomId) {
        return roomId == 1 ? "练习" : "竞技";
    }
    private String getRoomTypeNameEn(int roomId) {
        return roomId == 1 ? "practice" : "compete";
    }

    private void modifyDesk(WaterDesk desk, IoSession session) {
        WaterDesk old = this.waterDeskServiceDao.getWaterDeskByDeskId(desk.getId());
        String roomTypeName = getRoomTypeName(desk.getRoomId());
        String roomTypeNameEn = getRoomTypeNameEn(desk.getRoomId());
        if (!old.getName().equals(desk.getName())) {
            String content = (gameName + "：修改了" + roomTypeName + "桌，ID为" + desk.getId() + "，修改桌名为“" + desk.getName() + "”");
            String contentEn = (gameNameEn + ":Change the parameter of " + roomTypeNameEn + " table which ID is " + desk.getId() + " Its name has been changed to " + desk.getName());
            addAdminLog(session, desk, content, contentEn);
        }
        if (old.isAutoKickOut() != desk.isAutoKickOut()) {
            if (desk.isAutoKickOut() == 0) {
                String content = (gameName + "：修改了" + roomTypeName + "桌，ID为" + desk.getId() + "，关闭自动踢出挂机玩家");
                String contentEn = (gameNameEn + ": Change the parameter of " + roomTypeNameEn + " table which ID is " + desk.getId() + "Turn off the function of kicking out hang up player");
                addAdminLog(session, content, contentEn);
            } else {
                String content = (gameName + "：修改了" + roomTypeName + "桌，ID为" + desk.getId() + "，开启自动踢出挂机玩家");
                String contentEn = (gameNameEn + ": Change the parameter of " + roomTypeNameEn + " table which ID is " + desk.getId() + "Turn on the function of kicking out hang up player");
                addAdminLog(session, content, contentEn);
            }
        }
        if (old.getMinGold() != desk.getMinGold()) {
            String content = (gameName + "：修改了" + roomTypeName + "桌，ID为" + desk.getId() + "，修改最小携带为“”" + desk.getMinGold());
            String contentEn = (gameNameEn + ": Change the parameter of " + roomTypeNameEn + " table which ID is " + desk.getId() + " Change the min carry of coins to " + desk.getMinGold());
            addAdminLog(session, desk, content, contentEn);
        }
        if (old.getMaxSinglelineBet() != desk.getMaxSinglelineBet()) {
            String content = (gameName + "：修改了" + roomTypeName + "桌，ID为" + desk.getId() + "，修改最大单线押注为 " + desk.getMaxSinglelineBet() + "“");
            String contentEn = (gameNameEn + ":Change the parameter of " + roomTypeNameEn + " table which ID is " + desk.getId() + " Change the max single bet to " + desk.getMaxSinglelineBet());
            addAdminLog(session, desk, content, contentEn);
        }
        if (old.getMinSinglelineBet() != desk.getMinSinglelineBet()) {
            String content = (gameName + "：修改了" + roomTypeName + "桌，ID为" + desk.getId() + "，修改最小单线押注为 " + desk.getMinSinglelineBet() + "“");
            String contentEn = (gameNameEn + ":Change the parameter of " + roomTypeNameEn + " table which ID is " + desk.getId() + " Change the min single bet to " + desk.getMinSinglelineBet());
            addAdminLog(session, desk, content, contentEn);
        }
        if (old.getSinglechangeScore() != desk.getSinglechangeScore()) {
            String content = (gameName + "：修改了" + roomTypeName + "桌，ID为" + desk.getId() + "，修改单线押注为 " + desk.getSinglechangeScore() + "“");
            String contentEn = (gameNameEn + ":Change the parameter of " + roomTypeNameEn + " table which ID is " + desk.getId() + " Change the single bet to " + desk.getSinglechangeScore());
            addAdminLog(session, desk, content, contentEn);
        }
        if (old.getExchange() != desk.getExchange()) {
            String content = (gameName + "：修改了" + roomTypeName + "桌，ID为 " + desk.getId() + "，修改一币分值为“" + desk.getExchange() + "”");
            String contentEn = (gameNameEn + ":Change the parameter of " + roomTypeNameEn + " table which ID is " + desk.getId() + "   Change the coin value to " + desk.getExchange());
            addAdminLog(session, desk, content, contentEn);
        }
        if (old.getDiceSwitch() != desk.getDiceSwitch()) {
            if (desk.getDiceSwitch() == 0) {
                String content = (gameName + "：修改了" + roomTypeName + "桌，ID为 " + desk.getId() + "，修改比倍开关为“OFF”");
                String contentEn = (gameNameEn + " ： Change the parameter of " + roomTypeNameEn + " table which ID is " + desk.getId() + " Change the multiple comparison switch to OFF");
                addAdminLog(session, desk, content, contentEn);
            } else {
                String content = (gameName + "：修改了" + roomTypeName + "桌，ID为 " + desk.getId() + "，修改比倍开关为“ON”");
                String contentEn = (gameNameEn + " ： Change the parameter of " + roomTypeNameEn + " table which ID is " + desk.getId() + " Change the multiple comparison switch to ON");
                addAdminLog(session, desk, content, contentEn);
            }
        }
        if (old.getDiceDirectSwitch() != desk.getDiceDirectSwitch()) {
            if (desk.getDiceDirectSwitch() == 0) {
                String content = (gameName + "：修改了" + roomTypeName + "桌，ID为 " + desk.getId() + "，修改直接比倍开关为“OFF”");
                String contentEn = (gameNameEn + " ： Change the parameter of " + roomTypeNameEn + " table which ID is " + desk.getId() + " Change the direct multiple comparison switch to OFF");
                addAdminLog(session, desk, content, contentEn);
            } else {
                String content = (gameName + "：修改了" + roomTypeName + "桌，ID为 " + desk.getId() + "，修改直接比倍开关为“ON”");
                String contentEn = (gameNameEn + " ： Change the parameter of " + roomTypeNameEn + " table which ID is " + desk.getId() + " Change the direct multiple comparison switch to ON");
                addAdminLog(session, desk, content, contentEn);
            }
        }
        if (old.getDiceOverflow() != desk.getDiceOverflow()) {
            String content = (gameName + "：修改了" + roomTypeName + "桌，ID为 " + desk.getId() + "，修改比倍爆机值为“" + desk.getDiceOverflow() + "”");
            String contentEn = (gameNameEn + ": Change the parameter of " + roomTypeNameEn + " table which ID is  " + desk.getId() + " Change multiple comparison blasting machine value to " + desk.getDiceOverflow());
            addAdminLog(session, desk, content, contentEn);
        }
        if (old.getMainGameDiff() != desk.getMainGameDiff()) {
            String[] difficult = d(desk.getMainGameDiff());
            String content = (gameName + "：修改了" + roomTypeName + "桌，ID为" + desk.getId() + "，修改主游戏难度为“" + difficult[0] + "”");
            String contentEn = (gameNameEn + ":  Change the parameter of " + roomTypeNameEn + " table which ID is " + desk.getId() + "  Change the the winning rate of main game is " + difficult[1]);
            addAdminLog(session, desk, content, contentEn);
        }
        if (old.getDiceGameDiff() != desk.getDiceGameDiff()) {
            String[] difficult = d(desk.getDiceGameDiff());
            String content = (gameName + "：修改了" + roomTypeName + "桌，ID为" + desk.getId() + "，修改比倍中奖率为“" + difficult[0] + "”");
            String contentEn = (gameNameEn + " ： Change the parameter of " + roomTypeNameEn + " table which ID is " + desk.getId() + "  Change the multiple comparison winning rate to " + difficult[1]);
            addAdminLog(session, desk, content, contentEn);
        }
        if (old.getOnceExchangeValue() != desk.getOnceExchangeValue()) {
            String content = (gameName + "：修改了" + roomTypeName + "桌，ID为" + desk.getId() + "，修改上分设置为“" + desk.getOnceExchangeValue() + "”");
            String contentEn = (gameNameEn + ":Change the parameter of " + roomTypeNameEn + " table which ID is " + desk.getId() + "    Change the coin conversion to " + desk.getOnceExchangeValue());
            addAdminLog(session, desk, content, contentEn);
        }
        if (old.getState() != desk.getState()) {
            if (desk.getState() == 0) {
                String content = (gameName + "：修改了" + roomTypeName + "桌，ID为" + desk.getId() + "，修改桌状态为“锁定”");
                String contentEn = (gameNameEn + " ：Change the parameter of " + roomTypeNameEn + " table which ID is " + desk.getId() + " Change the table state as ”lock“");
                addAdminLog(session, desk, content, contentEn);
            } else {
                String content = (gameName + "：修改了" + roomTypeName + "桌，ID为" + desk.getId() + "，修改桌状态为“开放”");
                String contentEn = (gameNameEn + " ：Change the parameter of " + roomTypeNameEn + " table which ID is " + desk.getId() + " Change the table state as ”open“");
                addAdminLog(session, desk, content, contentEn);
            }
        }
        if (old.getAutoKickOut() != desk.getAutoKickOut()) {
            for (IoSession s : WaterSocketHandler.F) {
                AmfMessageSend.send(new Data(s, "manageService/autoKickOutDesk", new Object[]{desk.getId(), desk.getAutoKickOut()}));
            }
        }
    }

    private String[] d(int mainGameDiff) {
        String difficultyCn = "";
        String difficutyEn = "";
        switch (mainGameDiff) {
            case 0:
                difficultyCn = "最容易";
                difficutyEn = "easiest";

                break;
            case 1:
                difficultyCn = "容易";
                difficutyEn = "easy";

                break;
            case 2:
                difficultyCn = "难";
                difficutyEn = "difficult";

                break;
            case 3:
                difficultyCn = "最难";
                difficutyEn = "more difficult";

                break;
            case 4:
                difficultyCn = "死难";
                difficutyEn = "most difficult";
        }
        return new String[]{difficultyCn, difficutyEn};
    }

    public synchronized void addWaterDesk(WaterDesk desk, IoSession session) {
        WaterRoom wr = this.waterRoomServiceDao.getWaterRoomById(desk.getRoomId());
        if ((wr.getType() == 2) && (!GameParameterAssist.returnTrueMethod(gameType, wr.getDeskNum()))) {
            Map<String, Object> result = new HashMap<>();
            result.put("success", Boolean.FALSE);
            result.put("message", MyUtil.getProperties(resultInt(session), "deskNumOverrun"));
            GameParameterAssist.voidMethod("true");
            amfMessageSend(session, "addWaterDesk", result);
            return;
        }
        String deskName = desk.getName();
        if (this.waterDeskServiceDao.getQuantityByDeskName(deskName)) {
            amfMessageSend(session, "addWaterDesk", resultFormat(false, "桌子名称已存在"));
            return;
        }
        RoomStatus rs = GameParameterAssist.bD;
        if ((desk.getRoomId() == 1) && (rs.room1RemainNum7 < 1)) {
            amfMessageSend(session, "addWaterDesk", resultFormat(false, "桌子数量不足，不能新增"));
            return;
        }
        if ((desk.getRoomId() == 2) && (rs.room2RemainNum7 < 1)) {
            amfMessageSend(session, "addWaterDesk", resultFormat(false, "桌子数量不足，不能新增"));
            return;
        }
        Integer maxOrderBy = (Integer) this.waterDeskServiceDao.q_CreateSql("select max(orderBy) from WaterDesk where roomId = ?", new Object[]{desk.getRoomId()}).uniqueResult();
        if (maxOrderBy != null) {
            desk.setOrderBy(maxOrderBy + 1);
        } else {
            desk.setOrderBy(1);
        }
        int nCount = (Integer) this.waterDeskServiceDao.saveReturn(desk);
        Map<String, Object> result;
        if (nCount > 0) {
            result = resultFormat(true, "");
            if (desk.getRoomId() == 1) {
                rs.room1StartNum7 += 1;
                rs.room1RemainNum7 -= 1;
            }
            if (desk.getRoomId() == 2) {
                rs.room2StartNum7 += 1;
                rs.room2RemainNum7 -= 1;
            }
            for (Map.Entry<Integer, IoSession> entry : GameParameterAssist.be.entrySet()) {
                amfMessageSend(entry.getValue(), "syncRoomStatus", rs);
            }
        } else {
            result = resultFormat(false, "系统发生异常，请重试");
        }
        amfMessageSend(session, "addWaterDesk", result);
        String roomTypeName = getRoomTypeName(desk.getRoomId());
        String roomTypeNameEn = getRoomTypeNameEn(desk.getRoomId());
        String content = ("新增桌：“" + gameName + "：在" + roomTypeName + "添加了新桌，ID为  " + desk.getId() + "”");
        String contentEn = ("Add : “" + gameNameEn + "： Add a new table into " + roomTypeNameEn + " room which ID is" + desk.getId() + "”");
        addAdminLog(session, content, contentEn);
        for (IoSession s : WaterSocketHandler.F) {
            AmfMessageSend.send(new Data(s, "manageService/addDesk", new Object[]{desk}));
        }
        SystemConfig config = this.systemConfigServiceDao.getSystemConfig();
        if (config.getOpenWaterGame() == 0) {
            this.systemConfigServiceDao.ifTypeUpdate(gameType, 1);
            gameRunNotice(1);
        }
    }

    public void gameRunNotice(int openWaterGame) {
        SystemConfig config = this.systemConfigServiceDao.q_CreateSqlFilter("from SystemConfig", new Object[0]);
        int[] gs = new int[8];
        gs[0] = config.getOpenLuckGame();
        gs[1] = config.getOpenFishGame();
        gs[2] = config.getOpenCardGame();
        gs[3] = config.getOpenBulletGame();
        gs[4] = config.getOpenMermaidGame();
        gs[5] = config.getOpenLackGame();
        gs[6] = config.getOpenJoyGame();
        gs[7] = config.getOpenWaterGame();
        for (Map.Entry<Integer, IoSession> entry : GameParameterAssist.ba.entrySet()) {
            MessageSend.sendData(new StorageMethodEntity(entry.getValue(), "updateRunState", new Object[]{gs}));
        }
    }

    public synchronized void getWaterDeskList(IoSession session) {
        List<WaterDesk> waterDesks = this.waterDeskServiceDao.getWaterDesks();
        for (WaterDesk wd : waterDesks) {
            wd.setOnLineNumber(0);
            List<User> users = GameParameterAssist.br.get(wd.getId());
            if (users != null) {
                wd.setOnLineNumber(users.size());
            }
        }
        amfMessageSend(session, "getWaterDeskList", waterDesks.toArray(new WaterDesk[0]));
    }

    public synchronized void updateWaterDesk(WaterDesk desk, IoSession session) {
        String deskName = desk.getName();
        int deskId = desk.getId();
        if (this.waterDeskServiceDao.getQuantityByDeskNameAndDeskId(deskName, deskId)) {
            amfMessageSend(session, "updateWaterDesk", resultFormat(false, "桌子名称已存在"));
            return;
        }
        WaterDesk oldDesk = this.waterDeskServiceDao.getWaterDeskByDeskId(deskId);
        if ((oldDesk.getExchange() == desk.getExchange()) && (oldDesk.getMainGameDiff() == desk.getMainGameDiff()) && (oldDesk.getDiceGameDiff() == desk.getDiceGameDiff())) {
            desk.setMainGameSumDeFen(oldDesk.getMainGameSumDeFen());
            desk.setMainGameSumYaFen(oldDesk.getMainGameSumYaFen());
            desk.setDiceGameSumDeFen(oldDesk.getDiceGameSumDeFen());
            desk.setDiceGameSumYaFen(oldDesk.getDiceGameSumYaFen());
        }
        modifyDesk(desk, session);
        setWaterDesk(oldDesk, desk);
        this.waterDeskServiceDao.update(oldDesk);
        amfMessageSend(session, "updateWaterDesk", resultFormat(true, ""));
    }

    private WaterDesk setWaterDesk(WaterDesk oldDesk, WaterDesk desk) {
        oldDesk.setAutoKickOut(desk.getAutoKickOut());
        oldDesk.setDatetime(desk.getDatetime());
        oldDesk.setDiceDirectSwitch(desk.getDiceDirectSwitch());
        oldDesk.setDiceGameDiff(desk.getDiceGameDiff());
        oldDesk.setDiceGameSumDeFen(desk.getDiceGameSumDeFen());
        oldDesk.setDiceGameSumYaFen(desk.getDiceGameSumYaFen());
        oldDesk.setDiceOverflow(desk.getDiceOverflow());
        oldDesk.setDiceSwitch(desk.getDiceSwitch());
        oldDesk.setExchange(desk.getExchange());
        oldDesk.setId(desk.getId());
        oldDesk.setMainGameDiff(desk.getMainGameDiff());
        oldDesk.setMainGameSumDeFen(desk.getMainGameSumDeFen());
        oldDesk.setMainGameSumYaFen(desk.getMainGameSumYaFen());
        oldDesk.setMaxSinglelineBet(desk.getMaxSinglelineBet());
        oldDesk.setMinGold(desk.getMinGold());
        oldDesk.setMinSinglelineBet(desk.getMinSinglelineBet());
        oldDesk.setName(desk.getName());
        oldDesk.setOnceExchangeValue(desk.getOnceExchangeValue());
        oldDesk.setOrderBy(desk.getOrderBy());
        oldDesk.setRoomId(desk.getRoomId());
        oldDesk.setSinglechangeScore(desk.getSinglechangeScore());
        oldDesk.setState(desk.getState());
        oldDesk.setSumDeFen(desk.getSumDeFen());
        oldDesk.setSumYaFen(desk.getSumYaFen());
        return oldDesk;
    }

    public synchronized void deleteWaterDesk(int deskId, IoSession session) {
        RoomStatus rs = GameParameterAssist.bD;
        WaterDesk desk = this.waterDeskServiceDao.getWaterDeskByDeskId(deskId);
        if (desk.getRoomId() == 1) {
            rs.room1StartNum7 -= 1;
            rs.room1RemainNum7 += 1;
        }
        if (desk.getRoomId() == 2) {
            rs.room2StartNum7 -= 1;
            rs.room2RemainNum7 += 1;
        }
        for (Map.Entry<Integer, IoSession> entry : GameParameterAssist.be.entrySet()) {
            amfMessageSend(entry.getValue(), "syncRoomStatus", rs);
        }
        this.waterDeskServiceDao.deleteById(deskId);
        this.deskService.recordDeleteDesk(gameType, deskId, desk.getExchange());
        amfMessageSend(session, "deleteWaterDesk", resultFormat(true, ""));
        String content = ("删除桌：“水浒传：删除了ID为" + deskId + "的桌子”");
        String contentEn = ("Delete table:“Water margin ：Delete a table which ID is " + deskId + "”");
        addAdminLog(session, content, contentEn);
        for (IoSession s : WaterSocketHandler.F) {
            AmfMessageSend.send(new Data(s, "manageService/deleteDesk", new Object[]{desk}));
        }
        SystemConfig config = this.systemConfigServiceDao.getSystemConfig();
        if ((config.getOpenWaterGame() == 1) && (rs.room1StartNum7 == 0) && (rs.room2StartNum7 == 0)) {
            this.systemConfigServiceDao.ifTypeUpdate(gameType, 0);
            gameRunNotice(0);
        }
        GameParameterAssist.br.remove(desk.getId());
    }

    public synchronized void getWaterDeskUser(int deskId, IoSession session) {
        List<User> users = GameParameterAssist.br.get(deskId);
        if (users == null) {
            users = new ArrayList<>();
        }
        WaterDesk desk = this.waterDeskServiceDao.getWaterDeskByDeskId(deskId);
        for (User u : users) {
            User user = (User) this.userServiceDao.getById(u.getId());
            u.setGameGold(user.getGameGold());
            u.setExpeGold(user.getExpeGold());
            if (desk.getRoomId() == 1) {
                u.setCurrentGameScore(user.getExpeScore());
            } else {
                u.setCurrentGameScore(user.getGameScore());
            }
            u.setPromoterId(user.getPromoterId());
            u.setPromoterName(user.getPromoterName());
            u.setNickname(user.getNickname());
        }
        amfMessageSend(session, "getWaterDeskUser", users.toArray(new User[0]));
    }

    public synchronized void getWaterDeskData(int deskId, IoSession session) {
        Map<String, Object> result = new HashMap<>();
        WaterDesk desk = this.waterDeskServiceDao.getWaterDeskByDeskId(deskId);
        result.put("mainGameSumYaFen", desk.getMainGameSumYaFen());
        result.put("mainGameSumDeFen", desk.getMainGameSumDeFen());
        result.put("diceGameSumYaFen", desk.getDiceGameSumYaFen());
        result.put("diceGameSumDeFen", desk.getDiceGameSumDeFen());
        amfMessageSend(session, "getWaterDeskData", result);
    }

    public synchronized void cleanWaterDeskData(int deskId, IoSession session) {
        boolean isClean = this.waterDeskServiceDao.updateGameSumByDeskId(deskId);
        Map<String, Object> result;
        if (isClean) {
            result = resultFormat(true, "");
        } else {
            result = resultFormat(false, "系统发生异常，请重试");
        }
        amfMessageSend(session, "cleanWaterDeskData", result);
        String content = ("水浒传：清零了ID为" + deskId + "桌子的主游戏押分、主游戏总得分、比倍总押分、比倍总得分");
        String contentEn = ("Water margin ：Clean up the total bet and total score and of the table which ID is " + deskId);
        addAdminLog(session, content, contentEn);
        for (IoSession s : WaterSocketHandler.F) {
            AmfMessageSend.send(new Data(s, "manageService/cleanDesk", new Object[]{deskId}));
        }
    }

}
